home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gas_251.zip / bin_251 / ld / lexsup.c < prev    next >
C/C++ Source or Header  |  1994-10-12  |  13KB  |  464 lines

  1. /* Parse options for the GNU linker.
  2.    Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
  3.  
  4. This file is part of GLD, the Gnu Linker.
  5.  
  6. GLD is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GLD is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GLD; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "bfd.h"
  21. #include "sysdep.h"
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include "getopt.h"
  25. #include "bfdlink.h"
  26. #include "config.h"
  27. #include "ld.h"
  28. #include "ldmain.h"
  29. #include "ldmisc.h"
  30. #include "ldexp.h"
  31. #include "ldlang.h"
  32. #include "ldgram.h"
  33. #include "ldlex.h"
  34. #include "ldfile.h"
  35. #include "ldver.h"
  36.  
  37. /* Somewhere above, sys/stat.h got included . . . . */
  38. #if !defined(S_ISDIR) && defined(S_IFDIR)
  39. #define    S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
  40. #endif
  41.  
  42. /* Omit args to avoid the possibility of clashing with a system header
  43.    that might disagree about consts.  */
  44. unsigned long strtoul ();
  45.  
  46. static void set_default_dirlist PARAMS ((char *dirlist_ptr));
  47. static void set_section_start PARAMS ((char *sect, char *valstr));
  48.  
  49. void
  50. parse_args (argc, argv)
  51.      int argc;
  52.      char **argv;
  53. {
  54.   int ingroup = 0;
  55.  
  56.   /* Starting the short option string with '-' is for programs that
  57.      expect options and other ARGV-elements in any order and that care about
  58.      the ordering of the two.  We describe each non-option ARGV-element
  59.      as if it were the argument of an option with character code 1.  */
  60.  
  61.   const char *shortopts =
  62.     "-a:A:B::b:c:de:F::G:giL:l:Mm:NnO:o:R:rSsT:tu:VvXxY:y:()";
  63.  
  64.   /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
  65.  
  66. #define OPTION_CALL_SHARED        150
  67. #define OPTION_DEFSYM            (OPTION_CALL_SHARED + 1)
  68. #define OPTION_DYNAMIC_LINKER        (OPTION_DEFSYM + 1)
  69. #define OPTION_EB            (OPTION_DYNAMIC_LINKER + 1)
  70. #define OPTION_EL            (OPTION_EB + 1)
  71. #define OPTION_HELP            (OPTION_EL + 1)
  72. #define OPTION_IGNORE            (OPTION_HELP + 1)
  73. #define OPTION_MAP            (OPTION_IGNORE + 1)
  74. #define OPTION_NO_KEEP_MEMORY        (OPTION_MAP + 1)
  75. #define OPTION_NOINHIBIT_EXEC        (OPTION_NO_KEEP_MEMORY + 1)
  76. #define OPTION_NON_SHARED        (OPTION_NOINHIBIT_EXEC + 1)
  77. #define OPTION_OFORMAT            (OPTION_NON_SHARED + 1)
  78. #define OPTION_RELAX            (OPTION_OFORMAT + 1)
  79. #define OPTION_RETAIN_SYMBOLS_FILE    (OPTION_RELAX + 1)
  80. #define OPTION_RPATH            (OPTION_RETAIN_SYMBOLS_FILE + 1)
  81. #define OPTION_SHARED            (OPTION_RPATH + 1)
  82. #define OPTION_SONAME            (OPTION_SHARED + 1)
  83. #define OPTION_SORT_COMMON        (OPTION_SONAME + 1)
  84. #define OPTION_STATS            (OPTION_SORT_COMMON + 1)
  85. #define OPTION_TBSS            (OPTION_STATS + 1)
  86. #define OPTION_TDATA            (OPTION_TBSS + 1)
  87. #define OPTION_TTEXT            (OPTION_TDATA + 1)
  88. #define OPTION_TRADITIONAL_FORMAT    (OPTION_TTEXT + 1)
  89. #define OPTION_UR            (OPTION_TRADITIONAL_FORMAT + 1)
  90. #define OPTION_VERBOSE            (OPTION_UR + 1)
  91. #define OPTION_VERSION            (OPTION_VERBOSE + 1)
  92. #define OPTION_WARN_COMMON        (OPTION_VERSION + 1)
  93. #define OPTION_WARN_ONCE        (OPTION_WARN_COMMON + 1)
  94.  
  95.   static struct option longopts[] = {
  96.     {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
  97.     {"Bstatic", no_argument, NULL, OPTION_NON_SHARED},
  98.     {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
  99.     {"dc", no_argument, NULL, 'd'},
  100.     {"defsym", required_argument, NULL, OPTION_DEFSYM},
  101.     {"dll-verbose", no_argument, NULL, OPTION_VERSION}, /* Linux.  */
  102.     {"dn", no_argument, NULL, OPTION_NON_SHARED},
  103.     {"dp", no_argument, NULL, 'd'},
  104.     {"dy", no_argument, NULL, OPTION_CALL_SHARED},
  105.     {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
  106.     {"EB", no_argument, NULL, OPTION_EB},
  107.     {"EL", no_argument, NULL, OPTION_EL},
  108.     {"end-group", no_argument, NULL, ')'},
  109.     {"format", required_argument, NULL, 'b'},
  110.     {"help", no_argument, NULL, OPTION_HELP},
  111.     {"Map", required_argument, NULL, OPTION_MAP},
  112.     {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
  113.     {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
  114.     {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
  115.     {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
  116.     {"oformat", required_argument, NULL, OPTION_OFORMAT},
  117.     {"Qy", no_argument, NULL, OPTION_IGNORE},
  118.     {"qmagic", no_argument, NULL, OPTION_IGNORE}, /* Linux compatibility.  */
  119.     {"relax", no_argument, NULL, OPTION_RELAX},
  120.     {"retain-symbols-file", required_argument, NULL, OPTION_RETAIN_SYMBOLS_FILE},
  121.     {"rpath", required_argument, NULL, OPTION_RPATH},
  122.     {"shared", no_argument, NULL, OPTION_SHARED},
  123.     {"soname", required_argument, NULL, OPTION_SONAME},
  124.     {"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
  125.     {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
  126.     {"start-group", no_argument, NULL, '('},
  127.     {"stats", no_argument, NULL, OPTION_STATS},
  128.     {"static", no_argument, NULL, OPTION_NON_SHARED},
  129.     {"Tbss", required_argument, NULL, OPTION_TBSS},
  130.     {"Tdata", required_argument, NULL, OPTION_TDATA},
  131.     {"Ttext", required_argument, NULL, OPTION_TTEXT},
  132.     {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
  133.     {"Ur", no_argument, NULL, OPTION_UR},
  134.     {"verbose", no_argument, NULL, OPTION_VERBOSE},
  135.     {"version", no_argument, NULL, OPTION_VERSION},
  136.     {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
  137.     {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
  138.     {NULL, no_argument, NULL, 0}
  139.   };
  140.  
  141.   while (1)
  142.     {
  143.       /* getopt_long_only is like getopt_long, but '-' as well as '--' can
  144.      indicate a long option.  */
  145.       int longind;
  146.       int optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
  147.  
  148.       if (optc == -1)
  149.     break;
  150.  
  151.       switch (optc)
  152.     {
  153.     default:
  154.       xexit (1);
  155.     case 1:            /* File name.  */
  156.       lang_add_input_file (optarg, lang_input_file_is_file_enum,
  157.                    (char *) NULL);
  158.       break;
  159.  
  160.     case OPTION_IGNORE:
  161.       break;
  162.     case 'a':
  163.       /* For HP/UX compatibility.  Actually -a shared should mean
  164.              ``use only shared libraries'' but, then, we don't
  165.              currently support shared libraries on HP/UX anyhow.  */
  166.       if (strcmp (optarg, "archive") == 0)
  167.         config.dynamic_link = false;
  168.       else if (strcmp (optarg, "shared") == 0
  169.            || strcmp (optarg, "default") == 0)
  170.         config.dynamic_link = true;
  171.       else
  172.         einfo ("%P%F: unrecognized -a option `%s'\n", optarg);
  173.       break;
  174.     case 'A':
  175.       ldfile_add_arch (optarg);
  176.       break;
  177.     case 'b':
  178.       lang_add_target (optarg);
  179.       break;
  180.     case 'c':
  181.       ldfile_open_command_file (optarg);
  182.       parser_input = input_mri_script;
  183.       yyparse ();
  184.       break;
  185.     case OPTION_CALL_SHARED:
  186.       config.dynamic_link = true;
  187.       break;
  188.     case OPTION_NON_SHARED:
  189.       config.dynamic_link = false;
  190.       break;
  191.     case 'd':
  192.       command_line.force_common_definition = true;
  193.       break;
  194.     case OPTION_DEFSYM:
  195.       lex_redirect (optarg);
  196.       parser_input = input_defsym;
  197.       yyparse ();
  198.       break;
  199.     case OPTION_DYNAMIC_LINKER:
  200.       command_line.interpreter = optarg;
  201.       break;
  202.     case OPTION_EB:
  203.       command_line.endian = ENDIAN_BIG;
  204.       break;
  205.     case OPTION_EL:
  206.       command_line.endian = ENDIAN_LITTLE;
  207.       break;
  208.     case 'e':
  209.       lang_add_entry (optarg, 1);
  210.       break;
  211.     case 'F':
  212.       /* Ignore.  */
  213.       break;
  214.     case 'G':
  215.       {
  216.         char *end;
  217.         g_switch_value = strtoul (optarg, &end, 0);
  218.         if (*end)
  219.           einfo ("%P%F: invalid number `%s'\n", optarg);
  220.       }
  221.       break;
  222.     case 'g':
  223.       /* Ignore.  */
  224.       break;
  225.     case OPTION_HELP:
  226.       help ();
  227.       xexit (0);
  228.       break;
  229.     case 'L':
  230.       ldfile_add_library_path (optarg, true);
  231.       break;
  232.     case 'l':
  233.       lang_add_input_file (optarg, lang_input_file_is_l_enum,
  234.                    (char *) NULL);
  235.       break;
  236.     case 'M':
  237.       config.map_filename = "-";
  238.       break;
  239.     case 'm':
  240.       /* Ignore.  Was handled in a pre-parse.   */
  241.       break;
  242.     case OPTION_MAP:
  243.       config.map_filename = optarg;
  244.       break;
  245.     case 'N':
  246.       config.text_read_only = false;
  247.       config.magic_demand_paged = false;
  248.       break;
  249.     case 'n':
  250.       config.magic_demand_paged = false;
  251.       break;
  252.     case OPTION_NO_KEEP_MEMORY:
  253.       link_info.keep_memory = false;
  254.       break;
  255.     case OPTION_NOINHIBIT_EXEC:
  256.       force_make_executable = true;
  257.       break;
  258.     case 'O':
  259.       /* FIXME "-O<non-digits> <value>" used to set the address of
  260.          section <non-digits>.  Was this for compatibility with
  261.          something, or can we create a new option to do that
  262.          (with a syntax similar to -defsym)?
  263.          getopt can't handle two args to an option without kludges.  */
  264.       set_default_dirlist (optarg);
  265.       break;
  266.     case 'o':
  267.       lang_add_output (optarg, 0); 
  268.       break;
  269.     case OPTION_OFORMAT:
  270.       lang_add_output_format (optarg, (char *) NULL, (char *) NULL, 0);
  271.       break;
  272.     case 'i':
  273.     case 'r':
  274.       link_info.relocateable = true;
  275.       config.build_constructors = false;
  276.       config.magic_demand_paged = false;
  277.       config.text_read_only = false;
  278.       config.dynamic_link = false;
  279.       break;
  280.     case 'R':
  281.       /* The GNU linker traditionally uses -R to mean to include
  282.          only the symbols from a file.  The Solaris linker uses -R
  283.          to set the path used by the runtime linker to find
  284.          libraries.  This is the GNU linker -rpath argument.  We
  285.          try to support both simultaneously by checking the file
  286.          named.  If it is a directory, rather than a regular file,
  287.          we assume -rpath was meant.  */
  288.       {
  289.         struct stat s;
  290.  
  291.         if (stat (optarg, &s) >= 0
  292.         && ! S_ISDIR (s.st_mode))
  293.           {
  294.         lang_add_input_file (optarg,
  295.                      lang_input_file_is_symbols_only_enum,
  296.                      (char *) NULL);
  297.         break;
  298.           }
  299.       }
  300.       /* Fall through.  */
  301.     case OPTION_RPATH:
  302.       if (command_line.rpath == NULL)
  303.         command_line.rpath = buystring (optarg);
  304.       else
  305.         {
  306.           char *buf;
  307.  
  308.           buf = xmalloc (strlen (command_line.rpath)
  309.                  + strlen (optarg)
  310.                  + 2);
  311.           sprintf (buf, "%s:%s", command_line.rpath, optarg);
  312.           free (command_line.rpath);
  313.           command_line.rpath = buf;
  314.         }
  315.       break;
  316.     case OPTION_RELAX:
  317.       command_line.relax = true;
  318.       break;
  319.     case OPTION_RETAIN_SYMBOLS_FILE:
  320.       add_keepsyms_file (optarg);
  321.       break;
  322.     case 'S':
  323.       link_info.strip = strip_debugger;
  324.       break;
  325.     case 's':
  326.       link_info.strip = strip_all;
  327.       break;
  328.     case OPTION_SHARED:
  329.       link_info.shared = true;
  330.       break;
  331.     case OPTION_SONAME:
  332.       command_line.soname = optarg;
  333.       break;
  334.     case OPTION_SORT_COMMON:
  335.       config.sort_common = true;
  336.       break;
  337.     case OPTION_STATS:
  338.       config.stats = true;
  339.       break;
  340.     case 't':
  341.       trace_files = true;
  342.       break;
  343.     case 'T':
  344.       ldfile_open_command_file (optarg);
  345.       parser_input = input_script;
  346.       yyparse ();
  347.       break;
  348.     case OPTION_TBSS:
  349.       set_section_start (".bss", optarg);
  350.       break;
  351.     case OPTION_TDATA:
  352.       set_section_start (".data", optarg);
  353.       break;
  354.     case OPTION_TTEXT:
  355.       set_section_start (".text", optarg);
  356.       break;
  357.     case OPTION_TRADITIONAL_FORMAT:
  358.       config.traditional_format = true;
  359.       break;
  360.     case OPTION_UR:
  361.       link_info.relocateable = true;
  362.       config.build_constructors = true;
  363.       config.magic_demand_paged = false;
  364.       config.text_read_only = false;
  365.       config.dynamic_link = false;
  366.       break;
  367.     case 'u':
  368.       ldlang_add_undef (optarg);
  369.       break;
  370.     case OPTION_VERBOSE:
  371.       ldversion (1);
  372.       version_printed = true;
  373.       trace_file_tries = true;
  374.       break;
  375.     case 'v':
  376.     case 'V':
  377.       ldversion (0);
  378.       version_printed = true;
  379.       break;
  380.     case OPTION_VERSION:
  381.       ldversion (0);
  382.       version_printed = true;
  383.       break;
  384.     case OPTION_WARN_COMMON:
  385.       config.warn_common = true;
  386.       break;
  387.     case OPTION_WARN_ONCE:
  388.       config.warn_once = true;
  389.       break;
  390.     case 'X':
  391.       link_info.discard = discard_l;
  392.       break;
  393.     case 'x':
  394.       link_info.discard = discard_all;
  395.       break;
  396.     case 'Y':
  397.       set_default_dirlist (optarg);
  398.       break;
  399.     case 'y':
  400.       add_ysym (optarg);
  401.       break;
  402.     case '(':
  403.       if (ingroup)
  404.         {
  405.           fprintf (stderr,
  406.                "%s: may not nest groups (--help for usage)\n",
  407.                program_name);
  408.           xexit (1);
  409.         }
  410.       lang_enter_group ();
  411.       ingroup = 1;
  412.       break;
  413.     case ')':
  414.       if (! ingroup)
  415.         {
  416.           fprintf (stderr,
  417.                "%s: group ended before it began (--help for usage)\n",
  418.                program_name);
  419.           xexit (1);
  420.         }
  421.       lang_leave_group ();
  422.       ingroup = 0;
  423.       break;
  424.     }
  425.     }
  426.  
  427.   if (ingroup)
  428.     lang_leave_group ();
  429. }
  430.  
  431. /* Add the (colon-separated) elements of DIRLIST_PTR to the
  432.    library search path.  */
  433.  
  434. static void
  435. set_default_dirlist (dirlist_ptr)
  436.      char *dirlist_ptr;
  437. {
  438.   char *p;
  439.  
  440.   while (1)
  441.     {
  442.       p = strchr (dirlist_ptr, ':');
  443.       if (p != NULL)
  444.     *p = 0;
  445.       if (*dirlist_ptr)
  446.     ldfile_add_library_path (dirlist_ptr, true);
  447.       if (p == NULL)
  448.     break;
  449.       *p = ':';
  450.       dirlist_ptr = p + 1;
  451.     }
  452. }
  453.  
  454. static void
  455. set_section_start (sect, valstr)
  456.      char *sect, *valstr;
  457. {
  458.   char *end;
  459.   unsigned long val = strtoul (valstr, &end, 16);
  460.   if (*end)
  461.     einfo ("%P%F: invalid hex number `%s'\n", valstr);
  462.   lang_section_start (sect, exp_intop (val));
  463. }
  464.